之前在学校里面写的项目很少会用到 ES6 ,就算是用也只不过是将 const 啊、let 啊或者是 set 这些简单地用一用,现在在公司看到的项目才发觉,大家早就熟练地用上了 ES6 的东西,最近也在学着使用,发现有些东西使用 ES6 的语法来写的确方便很多,下面就介绍一下箭头函数:
箭头函数一般比一个函数表达式更短,并且不绑定自己的 this、argumrnts、super 或 new.target,适用于非方法函数,并且它们不能用作构造函数。
基础语法:
参数、返回值
1
2
3
4
5
6
7function(a) {
return a+1;
}
//=>:
a => a + 1;参数、操作、无返回值
1
2
3
4
5
6
7
8
9function(event) {
test1();
test2();
}
//=>
event => {
test1();
test2();
}参数、操作、有返回值(不忽略 return)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function(x) {
if( x > 0 ) {
return x * x;
}else {
return x + x;
}
}
//=>
x=> {
if( x > 0 ) {
return x * x;
}else {
return x + x;
}
}参数、返回值( {} 为函数体,可另外加括号表示返回值 )
1
2
3
4
5
6
7
8
9
10function(x) {
return {
foo: x
};
}
//=>
x => {
foo: x
}多参数( 利用括号 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15function(x,y,z,...rest) {
var i ,sum = x+y;
for( i = 0; r < rest.length; i++ ) {
sum += rest[i];
}
return sam;
}
// =>
( x,y,z,...rest ) => {
var i ,sum = x+y;
for( i = 0; r < rest.length; i++ ) {
sum += rest[i];
}
return sam;
}
作用:
箭头函数的引用有两方面的作用:
- 更简短的函数书写
- 对 this 的词法解析
短函数书写这块我们在上面的例子已经领略过了,这里就不提了,这里来说说 对 this 的词法解析。
- 不绑定 this
在箭头函数以前,每个新定义的函数都会有自己的 this 值,在面向对象风格的编程中,这会带来很多困扰。
eg:1
2
3
4
5
6
7
8function Person() {
this.age = 0;
serInterval(function growUp() {
//在非严格模式下, groupUp() 函数定义了内部的 this 为 全局对象而非 Person 中的 this
this.age ++;
},3000);
}
var p = new Person();
(1)闭包解决
在 ECMAScript 对此的解决方法是通过 this 值赋给变量,将变量放到闭包中去解决。
1 | function Person() { |
(2)bind 函数解决
.bind(this)
(3) 箭头函数
而箭头函数解决了这个情景的问题,它会捕捉其所在的上下文的 this 值,来作为自己的 this 值,因此下面的代码捕捉到的是 Person 中的 this:1
2
3
4
5
6
7function Person() {
this.age = 0;
setInterval( () => {
this.age++;
},3000 )
}
var p = new Person();
另外:
<1> 箭头函数的写法会忽略严格模式中与 this 相关的规则1
2
3
4
5var f = () => {
'use strict';
return this;
};
f() === window; //true
<2> call() 与 apply() 方法传入的只是参数,不会影响 this1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var adder = {
base: 1,
add : function(a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function(a) {
var f = v => v + this.base;
var b = {
base: 2,
};
return f.call(b, a);
},
}
console.log(adder.add(1)); // 2
console.log(adder.addThruCall(1));// 2
不绑定参数
箭头函数不会再内部暴露参数(arguments)
1
2
3
4
5
6
7
8
9
10
11var arguments = 42;//若 => 所在作用域上无 arguments 则内部的 arguments 为 undefined
var arr = () => arguments;
arr();//42
function foo() {
console.log(arguments[0]);//5
var f = (i) => arguments[0] + i;// 注意这里 arguments 取的是 foo 的参数,箭头函数是不会暴露内部参数的。
return f(2);
}
foo(5); // 7
箭头函数没有自己的 arguments,不过大多数情况下,rest 参数可以给出一个解决方案:
1 | function foo() { |
使用 new 操作符
箭头函数不能用作构造器,否则会抛出错误1
2var Foo = () => {};
var foo = new Foo();// Uncaught TypeError: Foo is not a constructor使用原型属性
箭头函数没有原型属性。1
2var Foo = () => {};
console.log(Foo.prototype);//undefined使用 yield 关键字
yield 关键字通常不能在箭头函数中使用(除非是嵌套在允许使用的函数内)。因此,箭头函数不能用作生成器。
补充:
- 返回文字表达式
用箭头函数返回一个文字表达式是行不通的。1
2
3
4
5
6
7
8var func = () => {
foo:1
};
//undefined
var func = () => {
foo: function() {};
}
// Uncaught SyntaxError: Unexpected token (
这是因为花括号(即 {} )里面的代码被解析为序列语句了(例如, foo 被认为是一个标签, 而非文字表达式的组成部分)。
所以,记得用圆括号把文字表达式包起来:
1 | var func = () => ( |
- 换行
箭头函数在参数与箭头间不可换行:
1 | var func = () |
- 解析顺序
箭头函数的箭头虽然不是操作符也不是运算符,但是会受操作符优先级的影响
1 | let callback; |